package com.yunlongn.async.log.impl;

import com.yunlongn.async.log.LogDo;

import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author yunlong.li
 */
public class MemoryScheduleServiceImpl extends AbstractScheduleLog{
    private final static ConcurrentMap<Object, LogDo> LOG_ENTITY_CONCURRENT_MAP = new ConcurrentHashMap<>();

    @Override
    protected void doSava(LogDo entity) {
        LOG_ENTITY_CONCURRENT_MAP.put(entity.getId(), entity);
    }

    @Override
    protected LogDo doQuery(String id) {
        return LOG_ENTITY_CONCURRENT_MAP.get(id);
    }

    @Override
    protected void doUpdate(LogDo entity) {
        if (LogDo.Stat.SUCCESS.getStat().equalsIgnoreCase(entity.getStatus())
                || LogDo.Stat.FAIL.getStat().equalsIgnoreCase(entity.getStatus())) {
            LOG_ENTITY_CONCURRENT_MAP.remove(entity.getId());
        } else {
            LOG_ENTITY_CONCURRENT_MAP.replace(entity.getId(), entity);
        }
    }

    @Override
    public Iterator<LogDo> loadNotFinishTask() {
        final Iterator<LogDo> log = LOG_ENTITY_CONCURRENT_MAP.values().iterator();
        return new Iterator<LogDo>() {

            LogDo nextLog;

            @Override
            public boolean hasNext() {
                while (log.hasNext()) {
                    LogDo entity = log.next();
                    if (entity.getRetryCnt() < entity.getFreePeriods().size()) {
                        nextLog = entity;
                        return true;
                    } else {
                        nextLog = null;
                    }
                }
                return false;
            }

            @Override
            public LogDo next() {
                return nextLog;
            }

            @Override
            public void remove() {
                log.remove();
            }
        };
    }

}
